// Copyright (c) 2023 CHANGLEI. All rights reserved.

import 'package:dio/dio.dart';

import 'package:flutter_grasp/src/gio/gio.dart';

/// 创建[Gio]
Gio createGio([GioBaseOptions? options]) => throw UnsupportedError('');

const _interceptor = GioInterceptor();

/// Created by changlei on 2020/8/26.
///
/// 创建[Dio]扩展Mixin
base mixin DioExtendsMixin on DioMixin {
  @override
  Interceptors get interceptors {
    final interceptors = super.interceptors;
    if (interceptors.whereType<GioInterceptor>().isEmpty) {
      interceptors.add(_interceptor);
    }
    return interceptors;
  }

  @override
  Future<Response<T>> fetch<T>(RequestOptions requestOptions) {
    final gioRequestOptions = _mergeOptions(requestOptions);
    setResponseDataType<T>(gioRequestOptions);
    return super.fetch(gioRequestOptions);
  }

  GioRequestOptions _mergeOptions(RequestOptions requestOptions) {
    if (requestOptions is GioRequestOptions) {
      return requestOptions;
    }
    final headers = <String, Object?>{...requestOptions.headers};
    final contentType = requestOptions.contentType;
    if (contentType != null) {
      headers.remove(Headers.contentTypeHeader);
    }
    final baseOptions = options;
    return GioRequestOptions(
      method: requestOptions.method,
      sendTimeout: requestOptions.sendTimeout,
      receiveTimeout: requestOptions.receiveTimeout,
      connectTimeout: requestOptions.connectTimeout,
      data: requestOptions.data,
      path: requestOptions.path,
      queryParameters: requestOptions.queryParameters,
      baseUrl: requestOptions.baseUrl,
      onReceiveProgress: requestOptions.onReceiveProgress,
      onSendProgress: requestOptions.onSendProgress,
      cancelToken: requestOptions.cancelToken,
      extra: requestOptions.extra,
      headers: headers,
      responseType: requestOptions.responseType,
      contentType: contentType,
      validateStatus: requestOptions.validateStatus,
      receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
      followRedirects: requestOptions.followRedirects,
      maxRedirects: requestOptions.maxRedirects,
      persistentConnection: requestOptions.persistentConnection,
      requestEncoder: requestOptions.requestEncoder,
      responseDecoder: requestOptions.responseDecoder,
      listFormat: requestOptions.listFormat,
      // ignore: invalid_use_of_internal_member
      sourceStackTrace: requestOptions.sourceStackTrace,
      validateCode: baseOptions is GioBaseOptions ? baseOptions.validateCode : null,
      keysOptions: baseOptions is GioBaseOptions ? baseOptions.keysOptions : null,
    );
  }
}
